home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 4
/
FM Towns Free Software Collection 4 - Disc 1.iso
/
t_os
/
tie
/
src
/
wc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-18
|
34KB
|
1,232 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <msdos.cf>
#include <egb.h>
#include <mos.h>
#include <fmc.h>
#include <snd.h>
#include "tie.h"
#include "cons.h"
#define TRUE 1
#define FALSE 0
#define ERR (-1)
#define OFS_Y 32 /* 全体をタイトルのぶん下げてある */
#define CARD_X 468
#define CARD_Y 20+OFS_Y
#define CARD_LEN 12
#define DRV_X 68
#define DRV_Y 20+OFS_Y
#define DRV_MAX 17 /* A - Q */
#define DRV_LEN 8
#define CLIP_SIZ 30
#define CLIP_LEN 2
#define CLIP_X 156
#define CLIP_DOWN (CLIP_X+CLIP_SIZ*8+8)
#define CLIP_UP (CLIP_DOWN+CLIP_LEN*8+6)
#define CLIP_Y (3+OFS_Y)
#define DSP_X 156
#define DSP_LEN 36
#define FNT_SIZ 16 /* 16ドットに固定 */
#define FNT_SPC_X 2
#define FNT_SPC_Y 1
#define DSP_Y (26+OFS_Y)
#define DSP_MAX 19 /* 一度に表示するファイルの数 */
#define SPC_Y 19 /* 一行の縦方向のドット数(全体) */
#define SIZ_Y 17 /* 一行の縦方向のドット数(文字部分) */
#define WIND_COL 5
#define STD_COL 14
#define BACK_COL 5
#define HIT_COL 6
#define BOX1_COL 7
#define BOX2_COL 8
#define XOR1_COL 14
#define XOR2_COL 3
#define ISDIR(c) (c->att&0x10)
#define IS_FLP 0x00
#define IS_CDR 0x01
#define IS_SCSI 0x02
#define IS_RAM 0x03
#define IS_MDC 0x04
#define IS_ROM 0x05
#define IS_NON 0xFF
#define DISKSTAT_UNKNOWN 0 /* 知らん */
#define DISKSTAT_READY 1 /* 準備よし */
#define DISKSTAT_NOTREADY 2 /* 準備できてない */
typedef struct _WCBUF
{
struct _WCBUF *next ;
short int mark ;
short int att ;
u_short time, date ;
u_long size ;
char name[14] ;
} WCBUF ;
typedef struct _DISK
{
int disktype ; /* ディスク種別 */
int drivenum ; /* ドライブ番号 */
int ready ; /* READY ? */
} DISK ;
static int drv_max = ERR ; /* 現在有効なドライブ数 */
static DISK disk[ DRV_MAX ] =
{
IS_NON,0,0, IS_NON,0,0, IS_NON,0,0, IS_NON,0,0, IS_NON,0,0, IS_NON,0,0,
IS_NON,0,0, IS_NON,0,0, IS_NON,0,0, IS_NON,0,0, IS_NON,0,0, IS_NON,0,0,
IS_NON,0,0, IS_NON,0,0, IS_NON,0,0, IS_NON,0,0, IS_NON,0,0,
} ;
static char *dev_name[] =
{
"FD ", "CD", "HD ", "RAM ", "MDC ", "ROM ", "????"
} ;
static CDBUF card[ CARD_MAX ] ;
static int CDRV = -1, event = ERR ;
static int click_pos = 0 ; /* パスリストのどこをクリックしたのか */
static int stat_sw ; /* マウスのスイッチ */
static char crrdir[256] ; /* 現在のカレント・ディレクトリ */
static int curpos = 12 ; /* 編集行のカーソル位置 */
static int mark_file = -1 ; /* マークされているファイル */
static WCBUF *mark_wp = NULL ; /* マークファイルのWCBUF */
extern void down_key_chk( int sw ) ;
extern void up_key_chk( int sw ) ;
extern int wc_del( int ) ;
extern void init_drv_table( void ) ;
/* READY かどうか調べる */
static int check_drive( int i )
{
auto u_int stat, ret ;
auto int devnum, j ;
auto DISK *dp ;
dp = &disk[ i ] ;
switch( dp->disktype )
{
case IS_FLP: devnum = 0x20 | dp->drivenum ; break ;
case IS_SCSI: devnum = 0xB0 | dp->drivenum ; break ;
case IS_CDR: devnum = 0xC0 | dp->drivenum ; break ;
case IS_RAM:
case IS_ROM: return( DISKSTAT_READY ) ;
default:
return( dp->ready = DISKSTAT_UNKNOWN ) ;
}
j = ( dp->disktype == IS_CDR ) ? 3 : 1 ;
while( j-- > 0 && ( ret = DKB_rdstatus( devnum, &stat ) ) == 0x8080 ) ;
switch( ret )
{
case 0x0000: return( dp->ready = DISKSTAT_READY ) ;
case 0x8001: return( dp->ready = DISKSTAT_NOTREADY ) ;
default: return( dp->ready = DISKSTAT_UNKNOWN ) ;
}
}
/* カレントドライブを変更する */
void chdrv( int no )
{
CDRV = no ;
init_drv_table() ;
if( check_drive( no ) != DISKSTAT_READY )
return ;
Registers.AX.R = 0x0E00 ;
Registers.DX.R = no ;
calldos() ;
}
/* カレントディレクトリを変更する */
void chdir( char *name )
{
init_drv_table() ;
Registers.AX.R = 0x3B00 ;
Registers.DX.R = (int)name ;
Registers.DS.R = getds() ;
calldos() ;
}
/* カレントドライブを通知する */
int getdrv( void )
{
Registers.AX.R = 0x1900 ; /* Get Current Disk Drive */
calldos() ;
return Registers.AX.LH.L & 0xFF ;
}
/* カレントディレクトリを通知する */
int getdir( char *name )
{
int drv ;
init_drv_table() ;
if( check_drive( CDRV ) != DISKSTAT_READY )
{
sprintf( name, "%c:", 'A'+CDRV ) ;
return CDRV ;
}
Registers.AX.R = 0x4700 ;
Registers.DX.R = 0x0000 ;
Registers.SI.R = (int)name+3 ;
Registers.DS.R = getds() ;
calldos() ;
*(name++) = 'A' + ( drv = CDRV ) ;
*(name++) = ':' ;
*(name++) = '\\' ;
if( *name != '\0' )
strcat( name, "\\" ) ;
return drv ;
}
static WCBUF *wc_read( char *arg, int mode )
{
static int opflg = FALSE ;
static struct
{
u_char dd_dmy[22] ;
u_short dd_time, dd_date ;
u_long dd_size ;
char dd_name[13] ;
} dta ;
auto WCBUF *wp ;
if( disk[ CDRV ].ready == DISKSTAT_NOTREADY )
return( NULL ) ;
if( opflg == FALSE )
{
Registers.AX.R = 0x1A00 ; /* ファイル検索時のバッファ指定 */
Registers.DX.R = (int)&dta ; /* ファイル検索時のバッファ */
Registers.DS.R = getds() ;
calldos() ;
Registers.AX.R = 0x4E00 ; /* 初回のファイル検索 */
Registers.CX.R = mode ; /* 検索するファイルの属性 */
Registers.DX.R = (int)arg ;
Registers.DS.R = getds() ;
opflg = TRUE ;
}
else
Registers.AX.R = 0x4F00 ; /* 2回目以降のファイル検索 */
calldos() ;
if( ( Registers.Flags & 0x0001 ) != 0 ) /* エラーチェック */
{
opflg = FALSE ;
return NULL ;
}
if( ( wp = (WCBUF *)malloc( sizeof( WCBUF ) ) ) != NULL )
{
wp->next = NULL ;
wp->mark = FALSE ;
wp->att = dta.dd_dmy[21] ;
wp->date = dta.dd_date ;
wp->time = dta.dd_time ;
wp->size = dta.dd_size ;
strcpy( wp->name, dta.dd_name ) ;
}
return wp ;
}
static char toup( char ch )
{
return toupper(ch) ;
}
static int patmatch( char *arg, char *nam )
{
int i,j;
for( ; *arg != '\0' && *nam != '\0' ; )
{
i = toup(*(arg++)) ;
j = toup(*(nam++)) ;
if( i == '*' )
{
do {
if( (i = toup(*(arg++))) == '\0' )
return TRUE ;
} while ( i == '*' || i == '?' ) ;
do {
if ( j == i && patmatch(arg,nam) == TRUE )
return TRUE;
} while ( (j = toup(*(nam++))) != '\0' );
if ( i == '.' && *arg == '*' )
return TRUE;
else
return FALSE;
}
else if ( i != '?' && i != j )
return FALSE;
}
if ( *arg == '\0' && *nam == '\0' )
return TRUE;
else
return FALSE;
}
/* 拡張子があれば、その先頭のポインタなければ¥0を返す */
static char *subname( register char *name )
{
static char *nul = "\0" ;
auto char *p ;
if( *name == '.' || ( p = strrchr( name, '.' ) ) == NULL )
name = nul ;
else
name = p + 1 ;
return name ;
}
static char *formname( char *name )
{
char *p;
static char tmp[ 14 ] ;
auto char tmp2[ 16 ] ;
strcpy( tmp2, name ) ;
if( *( p = subname( tmp2 ) ) != '\0' ) /* 拡張子あり */
*(p-1) = '\0' ;
sprintf( tmp, "%-8s %-3s", tmp2, p ) ;
return tmp ;
}
static int cmpname( REGS WCBUF *sp, REGS WCBUF *dp )
{
REGS int cd ;
if( ISDIR(sp) != ISDIR(dp) )
return ISDIR(sp) ? ERR : TRUE ;
if( ( cd = strcmp( subname(sp->name), subname(dp->name) ) ) != 0 )
return cd ;
return strcmp( sp->name, dp->name ) ;
}
static void wc_reset( WCBUF *wp )
{
WCBUF *tp ;
while( wp != NULL )
{
tp = wp->next ;
free( wp ) ;
wp = tp ;
}
}
static int wild_chk( char *file )
{
int i;
for( i = 0 ; i < CARD_MAX ; i++ ) {
if( card[i].mark != FALSE && patmatch( card[i].name, file ) )
return TRUE ;
}
return FALSE;
}
static WCBUF *wc_sort( WCBUF *sp, WCBUF *dp )
{
REGS WCBUF *tp ;
auto WCBUF tmp ;
tp = &tmp ;
if( ( tp->next = sp ) == NULL )
return dp ;
/* #define TEST */
#ifdef TEST
if( tp->next != NULL )
tp = tp->next ;
#else
while( tp->next != NULL )
{
if( cmpname( tp->next, dp ) >= 0 )
break ;
tp = tp->next ;
}
#endif
dp->next = tp->next ;
tp->next = dp ;
return tmp.next ;
}
static WCBUF *wc_open()
{
WCBUF *topwp = NULL ;
WCBUF *wp ;
if( getdrv() != CDRV ) /* カレントドライブが違う! */
return NULL ;
mos_ptn( 2 ) ;
while( ( wp = wc_read( "*.*", 0x31 ) ) != NULL )
{
if( wp->name[0] == '.' && wp->name[1] == '\0' )
free( wp ) ;
else if( ISDIR( wp ) || wild_chk( wp->name ) )
{
#ifdef TEST
wp->next = topwp ;
topwp = wp ;
#else
topwp = wc_sort( topwp, wp ) ;
#endif
}
else
free( wp ) ;
}
mos_ptn( 0 ) ;
return topwp ;
}
static void DSP_file_chk( REGS EVENT *ep, int x, int y, int sw )
{
y = y ; /* 意味なし ワーニング回避 */
switch( ep->now )
{
case EVT_ON_MOS: /* ボタンの上にいるときは、カーソルを変更 */
mos_ptn( 1 ) ;
break ;
case EVT_OFF_MOS:
mos_ptn( 0 ) ;
break ;
case EVT_CLIP_MOS: /* 押した時はへこむ */
mos_ptn( 1 ) ;
stat_sw = sw ;
DSP_clip_on( ep ) ;
break ;
case EVT_DOLACK_MOS: /* 押したまま、外れると戻る */
ep->now = EVT_NON ;
case EVT_MOVE_MOS:
DSP_clip_off( ep ) ;
mos_ptn( 0 ) ;
break ;
case EVT_SELECT_MOS: /* その場で離すと、実行 */
event = ep->no ;
click_pos = ( x - ep->x1 ) / 8 ;
DSP_clip_off( ep ) ;
mos_ptn( 0 ) ;
break ;
}
}
static void ITEM_clip( REGS EVENT *ep, int x, int y, int sw )
{
sw = sw, y = y ; /* 意味なし ワーニング回避 */
switch( ep->now )
{
case EVT_ON_MOS: /* ボタンの上にいるときは、カーソルを変更 */
case EVT_CLIP_MOS:
mos_ptn( 6 ) ;
break ;
case EVT_DOLACK_MOS: /* 外れたら戻す */
ep->now = EVT_NON ;
case EVT_MOVE_MOS:
case EVT_OFF_MOS:
mos_ptn( 0 ) ;
break ;
case EVT_SELECT_MOS: /* その場で離すと、その位置を覚える */
event = ep->no ;
curpos = ( x - ep->x1 ) / 8 ;
mos_ptn( 1 ) ;
break ;
}
}
static void down_key_chk( int sw )
{
wrt("▼", writepage, CLIP_DOWN+FNT_SPC_X, CLIP_Y+FNT_SPC_Y,
col_tbl[sw == FALSE ? 7:STD_COL],
col_tbl[BACK_COL], FNT_SIZ ) ;
}
static void up_key_chk( int sw )
{
wrt( "▲", writepage, CLIP_UP+FNT_SPC_X, CLIP_Y+FNT_SPC_Y,
col_tbl[sw == FALSE ? 7:STD_COL],
col_tbl[BACK_COL], FNT_SIZ ) ;
}
/* ファイル名の表示 */
static void dsp_name( REGS WCBUF *wp, int top, int num )
{
static char dmy[256] ;
sprintf( dmy, "%-12s ", formname( wp->name ) ) ;
if( ISDIR( wp ) )
sprintf( dmy + 13, " <DIR> " ) ;
else
sprintf( dmy + 13, "%8ld ", wp->size ) ;
sprintf( dmy + 22,"%02d-%02d-%02d %02d:%02d",
80+(wp->date >> 9),
(wp->date >> 5) & 0x0F,
wp->date & 0x1F,
wp->time >> 11,
(wp->time >> 5) & 0x3F ) ;
wrt( dmy, writepage, DSP_X+FNT_SPC_X, DSP_Y+FNT_SPC_Y+SPC_Y*num,
col_tbl[STD_COL],
/* col_tbl[ ( wp!=NULL && wp->mark != FALSE ) ? HIT_COL:BACK_COL ], */
col_tbl[ ( wp!=NULL && num == mark_file-top ) ? HIT_COL:BACK_COL ],
FNT_SIZ ) ;
}
/* ファイル一覧パネルの表示 */
static void dsp_all( REGS WCBUF *wp, int top, int re_write )
{
int i ;
char tmp[256], tmp2[256] ;
char *p ;
EVT_level_free( 101 ) ;
MOS_disp( MOS_OFF ) ;
strcpy( tmp, crrdir ) ;
if( ( p = strrchr( tmp, '\\' ) ) != NULL && strlen( tmp ) > 3 )
*p = '\0' ; /* 余計な \ をつぶす */
sprintf( tmp2, "%-29s", tmp ) ;
tmp2[29] = '\0' ;
wrt( tmp2, writepage, CLIP_X+FNT_SPC_X, CLIP_Y+FNT_SPC_Y,
col_tbl[STD_COL], col_tbl[BACK_COL], FNT_SIZ ) ;
if( re_write )
{
dsp_box( DSP_X-2,DSP_Y-2,
DSP_X+DSP_LEN*8+4+2,DSP_Y+(DSP_MAX-1)*SPC_Y+SIZ_Y+2,
BOX1_COL,BOX2_COL,WIND_COL);
}
for( i = 0 ; wp != NULL && i < DSP_MAX ; i++ )
{
dsp_box( DSP_X,DSP_Y+i*SPC_Y,
DSP_X+DSP_LEN*8+4,DSP_Y+i*SPC_Y+SIZ_Y,
BOX1_COL,BOX2_COL,
wp->mark != FALSE ? HIT_COL:BACK_COL ) ;
EVT_set_node(DSP_X,DSP_Y+i*SPC_Y,
DSP_X+DSP_LEN*8+4,DSP_Y+i*SPC_Y+SIZ_Y,
101,DSP_file_chk,i,FALSE ) ;
dsp_name( wp, top, i ) ;
wp = wp->next ;
}
for( ; i < DSP_MAX ; i++ )
dsp_box( DSP_X, DSP_Y+i*SPC_Y,
DSP_X+DSP_LEN*8+4, DSP_Y+i*SPC_Y+SIZ_Y,
BACK_COL, BACK_COL, BACK_COL ) ;
down_key_chk( wp != NULL ? TRUE:FALSE ) ;
up_key_chk( top > 0 ? TRUE:FALSE ) ;
MOS_disp( MOS_ON ) ;
}
/* ワイルドカード・パネルの表示 */
static void dsp_card( int flush )
{
auto int i;
static CDBUF cardbuf[ CARD_MAX ] ;
EVT_level_free( 102 ) ;
MOS_disp( MOS_OFF ) ;
if( flush )
dsp_box( CARD_X-2,CARD_Y-2,
CARD_X+CARD_LEN*8+4+2,CARD_Y+(CARD_MAX-1)*SPC_Y+SIZ_Y+2,
BOX1_COL,BOX2_COL,WIND_COL ) ;
for( i = 0 ; i < CARD_MAX ; i ++ )
{
if( card[i].name != NULL )
EVT_set_node( CARD_X,CARD_Y+i*SPC_Y,
CARD_X+CARD_LEN*8+4,CARD_Y+i*SPC_Y+SIZ_Y,
102,DSP_file_chk,i+DSP_MAX,FALSE);
if( flush || cardbuf[i].name != card[i].name ||
cardbuf[i].mark != card[i].mark )
{
cardbuf[i].name = card[i].name ;
cardbuf[i].mark = card[i].mark ;
if( card[i].name != NULL )
{
dsp_box( CARD_X,CARD_Y+i*SPC_Y,
CARD_X+CARD_LEN*8+4,CARD_Y+i*SPC_Y+SIZ_Y,
BOX1_COL,BOX2_COL,
card[i].name != NULL &&
card[i].mark != FALSE ? HIT_COL:BACK_COL);
wrt( formname(card[i].name),
writepage, CARD_X+FNT_SPC_X, CARD_Y+FNT_SPC_Y+SPC_Y*i,
COL_1,
col_tbl[card[i].mark != FALSE ? HIT_COL:BACK_COL],
FNT_SIZ ) ;
}
else
dsp_box( CARD_X,CARD_Y+i*SPC_Y,
CARD_X+CARD_LEN*8+4,CARD_Y+i*SPC_Y+SIZ_Y,
BACK_COL, BACK_COL, BACK_COL ) ;
}
}
MOS_disp( TRUE ) ;
}
static void init_drv_table( void )
{
int i ;
u_char info[200] ;
if( drv_max != ERR ) /* 既に初期化済 */
return ;
ESR_setupInfo( (char *)info ) ; /* システム情報取得 */
for( drv_max = i = 0 ; i < DRV_MAX ; i ++ )
{
switch( disk[i].disktype = info[0x30 + i * 2] )
{
case IS_FLP: /* FLOPPY DISK */
disk[i].drivenum = info[0x31 + i * 2] ; break ;
case IS_CDR: /* CD-ROM DRIVE */
disk[i].drivenum = 0 ; break ;
case IS_SCSI: /* SCSI HARD DISK */
disk[i].drivenum = info[0x31 + i * 2] >> 4 ; break ;
case IS_RAM: /* RAM DISK */
disk[i].drivenum = 0 ; break ;
case IS_ROM: /* ROM DISK */ /* 意味なし */
/*disk[i].drivenum = 0 ; break ;*/
case IS_MDC: /* MDC HARD DISK : 処理法が不明のため */
default: /* IS_NON(未割り当て) か 不明 */
disk[i].disktype = IS_NON ; /* 処理法が不明のため */
continue ;
}
drv_max ++ ;
}
/* getdir( (char *)info ) ;
CDRV = info[0] - 'A' ; */
CDRV = getdrv() ;
}
/* ドライブ名パネルの表示 */
static void dsp_drive( int re_write )
{
static int last_cdrv = -1 ;
int i, n, dt ;
init_drv_table() ;
EVT_level_free( 303 ) ;
MOS_disp( FALSE ) ;
if( re_write )
{
last_cdrv = -1 ;
dsp_box( DRV_X-2, DRV_Y-2,
DRV_X+DRV_LEN*8+4+2, DRV_Y+(drv_max-1)*(SPC_Y+4)+4+SIZ_Y+2,
BOX1_COL, BOX2_COL, WIND_COL ) ;
}
for( i = n = 0 ; i < DRV_MAX ; i ++ )
{
if( ( dt = disk[i].disktype ) != IS_NON )
{
if( re_write || i == last_cdrv || i == CDRV )
{
dsp_box( DRV_X, DRV_Y+n*(SPC_Y+4),
DRV_X+DRV_LEN*8+4, DRV_Y+n*(SPC_Y+4)+3+SIZ_Y,
BOX1_COL, BOX2_COL,
i == CDRV ? HIT_COL:BACK_COL ) ;
#define DEVICE_ICON
#ifdef DEVICE_ICON
if( dt == 0 && i < 3 ) /* 内蔵FDは特別扱い */
dt = 6 ;
DSP_ptn( DRV_X+FNT_SPC_X+7, DRV_Y+FNT_SPC_Y+(SPC_Y+4)*n+3,
14,12, drv_icn[i], 1 ) ;
DSP_ptn( DRV_X+FNT_SPC_X+25, DRV_Y+FNT_SPC_Y+(SPC_Y+4)*n+2,
31,14, dev_icn[dt], 1 ) ;
#else
char tmp[ 16 ] ;
sprintf( tmp, " %c: %s", i + 'A',
dev_name[ disk[i].disktype ] ) ;
wrt( tmp, writepage, DRV_X+FNT_SPC_X, DRV_Y+FNT_SPC_Y+SPC_Y*n,
col_tbl[STD_COL],
col_tbl[i == CDRV ? HIT_COL:BACK_COL], FNT_SIZ ) ;
#endif
}
EVT_set_node( DRV_X, DRV_Y+n*(SPC_Y+4),
DRV_X+DRV_LEN*8+4, DRV_Y+n*(SPC_Y+4)+3+SIZ_Y,
103, DSP_file_chk, i+DSP_MAX+CARD_MAX,FALSE ) ;
n ++ ;
}
}
MOS_disp( TRUE ) ;
last_cdrv = CDRV ;
}
/* 最上段の一行を表示 */
static void dsp_clip( void )
{
EVT_level_free( 104 ) ;
MOS_disp( OFF ) ;
dsp_box( CLIP_X-2,CLIP_Y-2, CLIP_UP+CLIP_LEN*8+4+3,CLIP_Y+SIZ_Y+2,
BOX1_COL,BOX2_COL,WIND_COL ) ;
EVT_set_node( CLIP_X,CLIP_Y, CLIP_X+CLIP_SIZ*8+4,CLIP_Y+SIZ_Y,
104,DSP_file_chk,503, OFF ) ;
dsp_box( CLIP_X,CLIP_Y, CLIP_X+CLIP_SIZ*8+4,CLIP_Y+SIZ_Y,
BOX1_COL,BOX2_COL,BACK_COL ) ;
wrt( " <<< FILE SELECTER >>> ", writepage,
CLIP_X+FNT_SPC_X, CLIP_Y+FNT_SPC_Y,
col_tbl[STD_COL], col_tbl[BACK_COL], FNT_SIZ ) ;
dsp_box( CLIP_DOWN,CLIP_Y, CLIP_DOWN+CLIP_LEN*8+4,CLIP_Y+SIZ_Y,
BOX1_COL,BOX2_COL,BACK_COL ) ;
down_key_chk( FALSE ) ;
EVT_set_node( CLIP_DOWN,CLIP_Y, CLIP_DOWN+CLIP_LEN*8+4,CLIP_Y+SIZ_Y,
104,DSP_file_chk,501, OFF ) ;
dsp_box( CLIP_UP,CLIP_Y, CLIP_UP+CLIP_LEN*8+4,CLIP_Y+SIZ_Y,
BOX1_COL,BOX2_COL,BACK_COL ) ;
up_key_chk( FALSE ) ;
EVT_set_node( CLIP_UP,CLIP_Y, CLIP_UP+CLIP_LEN*8+4,CLIP_Y+SIZ_Y,
104,DSP_file_chk,502, OFF ) ;
MOS_disp( ON ) ;
}
static void dsp_ttl( char *msg )
{
int len, xs ;
if( ( len = strlen( msg ) ) > 70 || len < 4 ) /* 表示しない */
return ;
xs = 320 - len*8/2 - 32 - 18 ;
dsp_box( xs,8, xs+len*8+64,28, 7,8,5 ) ;
wrt( msg, writepage, xs+32,10, COL_14,COL_5, 16 ) ;
}
static void clr_scrn()
{
MOS_disp( FALSE ) ;
EGB_color( egbwork,1,0 ) ;
EGB_clearScreen( egbwork ) ;
MOS_disp( TRUE ) ;
}
static void click_cancel()
{
event = 500 ; /* キャンセル */
}
/* ファイル名入力ダイアログの表示 */
static int FNAM_X, FNAM_Y ;
static void dsp_filename( int keyin )
{
int x,y, xs,ys ;
x = FNAM_X = DSP_X ;
y = FNAM_Y = DSP_Y+(DSP_MAX-1)*SPC_Y+SIZ_Y+6 ;
MOS_disp( MOS_OFF ) ;
dsp_box( x-2,y-2, ( xs = x+DSP_LEN*8+4+2 ),y+SIZ_Y+2+2,
BOX1_COL,BOX2_COL,WIND_COL ) ;
if( keyin ) /* テキスト入力行 */
{
dsp_box( x+1,y, x+8*12+3,y+SIZ_Y+2, 1,1,15 ) ;
EVT_set_node( x+1,y, x+8*12+3,y+SIZ_Y+2, 104,ITEM_clip,600, OFF ) ;
}
x = xs - 98 ;
xs = 5*8 + FNT_SPC_X * 2 + 2 ;
ys = SIZ_Y + FNT_SPC_Y * 2 ;
dsp_box( x,y, x+xs,y+ys, BOX1_COL,BOX2_COL,BACK_COL ) ;
EVT_set_node( x,y, x+xs,y+ys, 104,DSP_file_chk,504, OFF ) ;
wrt( "決 定", writepage, x+FNT_SPC_X+2,y+FNT_SPC_Y+1,
col_tbl[STD_COL],col_tbl[BACK_COL], FNT_SIZ ) ;
x += 48 ;
dsp_box( x,y, x+xs,y+ys, BOX1_COL,BOX2_COL,BACK_COL ) ;
EVT_set_node( x,y, x+xs,y+ys, 104,DSP_file_chk,500, OFF ) ;
wrt( "中 止", writepage, x+FNT_SPC_X+2,y+FNT_SPC_Y+1,
col_tbl[STD_COL],col_tbl[BACK_COL], FNT_SIZ ) ;
MOS_disp( MOS_ON ) ;
}
/* ファイルを選択する */
char *file_select( char *def_file, char *msg, CDBUF wc[], int dirflag )
{
auto int i, top ;
auto int keyin ;
auto WCBUF *topwp ;
auto WCBUF *twp, *wp ;
auto char *file = NULL ;
auto char *p ;
auto int ch, win_close = TRUE ;
auto char filenamebuf[16] ;
auto int now_mouse, now_mark, db ;
static int last_mouse = 0 ;
static int last_mark = 0 ;
if( def_file == NULL )
keyin = FALSE ;
else
{
keyin = TRUE ;
strcpy( crrdir, def_file ) ;
if( ( p = strrchr( crrdir, '\\' ) ) != NULL && p[1] != '\0' )
{
strcpy( filenamebuf, p+1 ) ;
*p = '\0' ;
if( strlen( crrdir ) < 3 )
crrdir[2] = '\\', crrdir[3] = '\0' ;
chdrv( toupper( crrdir[0] ) - 'A' ) ;
chdir( crrdir ) ;
}
else
filenamebuf[0] = '\0' ; /* こんなことはないハズ・・・ */
}
memcpy( card, wc, sizeof( card ) ) ;
getdir( crrdir ) ;
MOS_disp( FALSE ) ;
MOS_writePage( 1 ) ;
MOS_horizon ( MIN_HORIZON, MAX_HORIZON ) ;
MOS_vertical( MIN_VERTICAL, MAX_VERTICAL ) ;
DSP_writePage( egbwork, 1 ) ;
EVT_control_cancel( FALSE ) ; /* 右クリック・キャンセルの使用停止 */
EVT_set_ground( 110, click_cancel ) ;
EVT_control_ground( TRUE ) ; /* 余白クリックでキャンセル */
clr_scrn() ;
dsp_clip() ;
dsp_drive( TRUE ) ;
dsp_card( TRUE ) ;
dsp_ttl( msg ) ;
dsp_filename( keyin ) ;
topwp = twp = wc_open() ;
mark_file = -1 ;
dsp_all( twp, 0, TRUE ) ;
top = 0 ;
KAN_dispMode() ; /* モード再表示 */
MOS_disp( MOS_ON ) ;
keyflush() ;
for( ; ; )
{
if( keyin && win_close )
{
wind_open( FNAM_X+3,FNAM_Y+2,12, &curpos, 1,15,5, filenamebuf ) ;
win_close = FALSE ;
}
event = ERR ;
while( 1 )
{
EVT_loop( 100,200 ) ;
if( event != ERR || kbhit( OFF ) != FALSE )
break ;
}
if( kbhit( OFF ) != FALSE ) /* キー入力センス */
{
if( ( ch = getch() ) == 0x1B ) /* エスケープで中止 */
event = 500 ;
else if( ch == 0x8073 ) /* 実行キーで実行 */
event = 504 ;
else
{
event = ERR ;
if( keyin && ch != 0x0D ) /* リターンキーは無視 */
putch( ch ) ;
}
}
if( event == ERR )
continue ;
if( event == 600 ) /* カーソル移動 */
win_close = TRUE ;
if( event == 500 ) /* キャンセル */
break ;
else if( event == 501 ) /* 下矢印 */
{
for( i = DSP_MAX ,wp = twp ; i > 0 && wp != NULL ; i-- )
wp = wp->next ;
if( wp != NULL )
{
top += DSP_MAX ;
twp = wp ;
dsp_all( twp, top, FALSE ) ;
}
}
else if( event == 502 ) /* 上矢印 */
{
if( top > 0 )
{
top -= DSP_MAX ;
for( i = 0 ,wp = topwp ; i < top && wp != NULL ; i++ )
wp = wp->next ;
twp = wp ;
dsp_all( twp, top, FALSE ) ;
}
}
else if( event == 503 ) /* 上方へ移動 */
{
if( click_pos < strlen( crrdir ) )
{
if( click_pos < 3 ) /* ルート */
*( crrdir + 3 ) = '\0' ;
else
{
for( p = crrdir + click_pos ; *p && *p != '\\' ; p ++ ) ;
*p = '\0' ;
}
chdir( crrdir ) ;
getdir( crrdir ) ;
wc_reset( topwp ) ;
topwp = twp = wc_open() ;
mark_file = -1 ;
dsp_all( twp, 0, FALSE ) ;
top = 0 ;
}
}
else if( event == 504 ) /* 決定 */
{
if( keyin )
wind_close(), win_close = TRUE ;
if( mark_file == -1 ) /* 無視 */
if( !( keyin && strlen( filenamebuf ) > 0 ) )
continue ;
if( keyin )
strcat( crrdir, filenamebuf ) ; /* フルパスにして渡す */
else
{
if( ISDIR( mark_wp ) && dirflag == OFF )
continue ;
strcat( crrdir, mark_wp->name ) ; /* フルパスにして渡す */
if( ISDIR( mark_wp ) )
strcat( crrdir, "\x10" ) ; /* 末尾に0x10を付加 */
}
file = crrdir ;
break ;
}
else if( event < DSP_MAX ) /* ファイルを選択 */
{
for( i = 0, wp = twp ; i < event && wp != NULL ; i++ )
wp = wp->next ;
if( rbtn( stat_sw ) == TRUE ) /* 右クリックによる選択 */
{
char tmp[ 128 ] ;
if( *( p = subname( wp->name ) ) != '\0' )
{ /* 拡張子があれば */
sprintf( tmp, "*.%s", p ) ;
event = wc_apend( tmp, TRUE ) ;
goto RE_PRINT ;
}
continue ;
}
/* ダブル・クリックの確認 */
now_mouse = MOS_getTime() ;
now_mark = event + top ;
if( now_mark == last_mark && now_mouse <= last_mouse + 15 )
db = TRUE ;
else
db = FALSE ;
last_mouse = now_mouse ;
last_mark = now_mark ;
if( ISDIR( wp ) && db ) /* 指定のディレクトリへ移動 */
{
chdir( wp->name ) ;
getdir( crrdir ) ;
wc_reset( topwp ) ;
topwp = twp = wc_open() ;
mark_file = -1 ;
dsp_all( twp, 0, FALSE ) ;
top = 0 ;
}
else /* マークのセットと解除 */
{
if( mark_file == now_mark )
{
mark_file = -1 ;
MOS_disp( MOS_OFF ) ;
dsp_name( wp, top, event ) ;
MOS_disp( MOS_ON ) ;
}
else
{
MOS_disp( MOS_OFF ) ;
if( mark_file >= top && mark_file <= top + DSP_MAX )
{
int tmp = mark_file - top ;
mark_file = -1 ;
dsp_name( mark_wp, top, tmp ) ;
}
mark_file = now_mark ;
mark_wp = wp ;
dsp_name( wp, top, event ) ;
MOS_disp( MOS_ON ) ;
}
if( keyin ) /* キー入力可能 */
{
wind_close() ;
win_close = TRUE ;
dsp_box( FNAM_X+1,FNAM_Y,
FNAM_X+8*12+3,FNAM_Y+SIZ_Y+2, 1,1,15 ) ;
strcpy( filenamebuf, wp->name ) ;
}
}
}
else if( ( event -= DSP_MAX ) < CARD_MAX ) /* ワイルド・カード */
{
if( rbtn( stat_sw ) == TRUE ) /* 右クリックによる選択 */
{
if( wc_del( event ) != ERR )
goto RE_PRINT ;
continue ;
}
if( card[event].name != NULL )
{
card[event].mark = card[event].mark != FALSE ? FALSE:TRUE ;
RE_PRINT:
dsp_card( FALSE ) ;
/* "*.*" が押されてない時だけ */
if( event == 0 || card[0].mark == FALSE )
{
wc_reset( topwp ) ;
topwp = twp = wc_open() ;
mark_file = -1 ;
dsp_all( topwp, 0, FALSE ) ;
top = 0 ;
}
}
}
else if( ( event -= CARD_MAX ) < DRV_MAX ) /* ドライブ・セレクト */
{
CDRV = event ;
dsp_drive( FALSE ) ;
mos_ptn( 2 ) ;
chdrv( event ) ;
getdir( crrdir ) ;
wc_reset( topwp ) ;
topwp = twp = wc_open() ;
mark_file = -1 ;
dsp_all( twp, 0, FALSE ) ;
top = 0 ;
}
}
EVT_level_free( 101 ) ;
EVT_level_free( 102 ) ;
EVT_level_free( 103 ) ;
EVT_level_free( 104 ) ;
EVT_level_free( 105 ) ;
EVT_level_free( 110 ) ;
wind_close() ;
wc_reset( topwp ) ;
clr_scrn() ;
EVT_control_ground( FALSE ) ;
EVT_control_cancel( TRUE ) ; /* 右クリック・キャンセルの使用再開 */
memcpy( wc, card, sizeof( card ) ) ;
return file ;
}
/* 削除する。失敗したらERRを返す */
static int wc_del( int no )
{
int i, j ;
int find ;
if( !card[no].allocate || card[no].name == NULL )
return ERR ;
free( card[no].name ) ;
for( i = no ; i < CARD_MAX ; i ++ )
{
find = FALSE ;
for( j = i + 1 ; j < CARD_MAX ; j ++ )
if( card[j].name != NULL )
{
card[i].name = card[j].name ;
card[i].mark = card[j].mark ;
card[i].allocate = card[j].allocate ;
card[j].name = NULL ;
card[j].mark = FALSE ;
card[i].allocate = TRUE ;
find = TRUE ;
break ;
}
if( !find )
{
card[i].name = NULL ;
card[i].mark = FALSE ;
card[i].allocate = TRUE ;
break ;
}
}
return( ERR+1 ) ;
}
/* ワイルドーカードを追加する。
登録成功か、すでに登録されていた場合はスロット番号を返す。
失敗なら ERR を返す */
int wc_apend( char *name, int mode )
{
int i ;
char *p ;
if( ( p = strrchr( name, '\\' ) ) != NULL )
name = p + 1 ;
for( p = name = strdup( name ) ; *p != '\0' ; p ++ )
*p = toup( *p ) ;
for( i = 0 ; i < CARD_MAX ; i++ )
if( card[i].name != NULL && strcmp( card[i].name, name ) == 0 )
{
if( mode == TRUE )
card[i].mark = card[i].mark != FALSE ? FALSE:TRUE ;
return( i ) ;
}
for( i = 0 ; i < CARD_MAX ; i++ )
{
if( card[i].name == NULL )
{
card[i].name = name ;
card[i].mark = mode ;
return( i ) ;
}
}
return( ERR ) ;
}